#include "server.h"

stackDir_t* stackDirInit(void){
    stackDir_t* p = (stackDir_t *)calloc(1,sizeof(stackDir_t));
    return p;
}

int push(stackDir_t* dirStack, int dir){
    stackNode_t* newNode = (stackNode_t *)calloc(1, sizeof(stackNode_t));
    newNode->dir = dir;
    if(dirStack->stackSize == 0){
        dirStack->head = newNode;
        dirStack->tail = newNode;
    }else{
        dirStack->tail->pnext = newNode;
        dirStack->tail = newNode;
    }
    ++dirStack->stackSize;
    return 0;
}

int top(stackDir_t* dirStack){
    int n = dirStack->tail->dir;
    return n;
}

int pop(stackDir_t* dirStack){
    stackNode_t* tmp = dirStack->tail;
    if(dirStack->stackSize == 1){
        dirStack->head = NULL;
        dirStack->tail =NULL;
    }else{
        stackNode_t* cur = dirStack->head;
        while(cur->pnext != dirStack->tail){
            cur = cur->pnext;
        }
        dirStack->tail = cur;
        cur->pnext = NULL;
    }
    free(tmp);
    --dirStack->stackSize;
    return 0;
}

int delstack(stackDir_t* dirStack){
    stackNode_t* cur = dirStack->head;
    stackNode_t* tmp = dirStack->head;
    while(cur){
        cur = cur->pnext;
        free(tmp);
        tmp = cur;
    }
    free(dirStack);
    return 0;
}

int pwd(stackDir_t* dirStack,MYSQL* mysql,char* pwds){
    int cur = top(dirStack);
    char sql[1024];
    sprintf(sql,"select path from file where id = %d;",cur);
    int qret = mysql_query(mysql,sql);
    if(qret != 0){
        fprintf(stderr,"%s:%s\n","mysql_query",mysql_error(mysql));
    }
    LOG_ERROR_CHECK(qret,!0,"mysql_query in login.");

    MYSQL_RES* result = mysql_store_result(mysql);
    MYSQL_ROW row = mysql_fetch_row(result);
    memcpy(pwds,row[0],strlen(row[0]) + 1);
    return 0;
}

int cdastep(stackDir_t* dirStack,char* dir,char* usrname,MYSQL* mysql){
    char workpath[513] = {0};
    pwd(dirStack,mysql,workpath);
    if(strcmp(dir,"..") == 0){
        pop(dirStack);
    }else if(strcmp(dir,".") == 0){
        //识别为'.'时什么都不做
    }else{
        //获取绝对虚拟路径
        if(dirStack->stackSize == 1){
            strcat(workpath,dir);
        }else{
            strcat(workpath,"/");
            strcat(workpath,dir);
        }
        //检验cd的对象是否存在
        char sql[1024] = {0};
        sprintf(sql,"select * from file where user_name = '%s' AND path = '%s' AND type = 'd';",usrname,workpath);
        int qret = mysql_query(mysql,sql);
        if(qret != 0){
            fprintf(stderr,"%s:%s\n","mysql_query",mysql_error(mysql));
        }
        MYSQL_RES* result = mysql_store_result(mysql);
        MYSQL_ROW row = mysql_fetch_row(result);
        if(row == NULL){
            return -1;
        }else{
            int cur = atoi(row[0]);
            push(dirStack,cur);
        }
    }
    return 0;
}

int cd(stackDir_t* dirStack,char* pathname,char* usrname,MYSQL* mysql){
    char* args[MAXSIZE];
    char* saveptr;
    int flag = 0;//判断是否为绝对
    if(pathname[0] == '/'){
        flag = 1;
    }
    //获取绝对虚拟路径
    char vrpath[512] = {0};
    getvrpath(pathname,vrpath,dirStack,mysql);

    char* token = strtok_r(pathname,"/",&saveptr);
    int i = 0;
    while(token != NULL && i < MAXSIZE - 1){
        args[i++] = token;
        token = strtok_r(NULL,"/",&saveptr);
    }
    args[i] = NULL;
    if(i == 0 || pathname[0] == '\0'){
        while(dirStack->stackSize > 1){
            pop(dirStack);
        }
    }
    else if(i == 1){
        int ret = cdastep(dirStack,args[0],usrname,mysql);
        if(ret == -1){
            return -1;
        }
    }else{
        if(flag == 1){//绝对路径
            while(dirStack->stackSize > 1){
                pop(dirStack);
            }
            int k = 0;
            while(args[k]){
                int ret = cdastep(dirStack,args[k],usrname,mysql);
                if(ret == -1){
                    return -1;
                }
                ++k;
            }
        }else{//相对路径
            int k = 0;
            while(args[k]){
                int ret = cdastep(dirStack,args[k],usrname,mysql);
                if(ret == -1){
                    return -1;
                }
                ++k;
            }
        }
    }
    return 0;
}

char** ls(stackDir_t* dirStack,MYSQL* mysql){
    int cur = top(dirStack);
    char** lsdir = (char**)calloc(MAXSIZE,sizeof(char *));
    char sql[1024] = {0};
    sprintf(sql,"select file_name from file where parent_id = %d AND is_delete = 0;",cur);
    int qret = mysql_query(mysql,sql);
    if(qret != 0){
        fprintf(stderr,"%s:%s\n","mysql_query",mysql_error(mysql));
    }
    MYSQL_RES* result = mysql_store_result(mysql);
    int rows = mysql_num_rows(result);
    MYSQL_ROW row;
    int i = 0;
    while(i < rows){
        row = mysql_fetch_row(result);
        if(i == 0 && row == NULL){
            lsdir[0] = NULL;
            return lsdir;
        }
        char* p = (char *)malloc(strlen(row[0]) + 1);
        memcpy(p,row[0],strlen(row[0]) + 1);
        lsdir[i++] = p;
    }
    lsdir[i] = NULL;
    return lsdir;
}

int freeLS(char** lsconbin){
    int i = 0;
    while(lsconbin[i]){
        free(lsconbin[i]);
        ++i;
    }
    return 0;
}

//检验输入的绝对路径还是相对路径，获取绝对虚拟路径
int getvrpath(const char* pathname,char* vrpath,stackDir_t* dirStack,MYSQL* mysql){
    if(pathname[0] == '/'){//绝对路径
        memcpy(vrpath,pathname,strlen(pathname) + 1);
    }else{
        char workpath[512] = {0};
        pwd(dirStack,mysql,workpath);
        strcat(vrpath,workpath);
        if(dirStack->stackSize == 1){
            strcat(vrpath,pathname);
        }else{
            strcat(vrpath,"/");
            strcat(vrpath,pathname);
        }
    }
    return 0;
}

int info_file(char* name,int* parent_id,char* vrpath,char* usrname,MYSQL* mysql){
    char copy[512] = {0};
    memcpy(copy,vrpath,strlen(vrpath));
    int n = strlen(copy);
    while(copy[n] != '/'){
        --n;
    }
    int k = n + 1;
    int i = 0;
    while(copy[k] != '\0'){
        name[i++] = copy[k++];
    }
    name[i] = '\0';
    if(n == 0){
        copy[n + 1] = '\0';
    }else{
        copy[n] = '\0';
    }
    char sql[1024] = {0};
    sprintf(sql,"select id from file where user_name = '%s' AND path = '%s' AND type = 'd';",usrname,copy);
    int qret = mysql_query(mysql,sql);
    if(qret != 0){
        fprintf(stderr,"%s:%s\n","mysql_query",mysql_error(mysql));
    }
    MYSQL_RES* result = mysql_store_result(mysql);
    MYSQL_ROW row = mysql_fetch_row(result);
    LOG_ERROR_CHECK(row[0],NULL,"ERROR in info_file.\n");
    if(row[0] == NULL){
        return -1;
    }
    *parent_id = atoi(row[0]);
    return 0;
}

int my_mkdir(stackDir_t* dirStack,MYSQL* mysql,char* pathname,char* usrname){
    char vrpath[512] = {0};
    getvrpath(pathname,vrpath,dirStack,mysql);
    printf("vrpath = %s\n",vrpath);
    char filename[128] = {0};
    int parent_id;
    int ret = info_file(filename,&parent_id,vrpath,usrname,mysql);
    if(ret == -1){
        return -1;
    }
    printf("filename = %s, parent_id = %d\n",filename, parent_id);
    char sql[1024] = {0};
    sprintf(sql,"insert into file (file_name,user_name,parent_id,type,path) values ('%s','%s',%d,'d','%s');",filename,usrname,parent_id,vrpath);
    int qret = mysql_query(mysql,sql);
    if(qret != 0){
        fprintf(stderr,"%s:%s\n","mysql_query",mysql_error(mysql));
    }
    return 0;
}

int my_rmdir(stackDir_t* dirStack,MYSQL* mysql,char* pathname,char* usrname){
    char vrpath[512] = {0};
    getvrpath(pathname,vrpath,dirStack,mysql);
    char sql[1024] = {0};
    sprintf(sql,"update file set is_delete = 1 where path = '%s' AND user_name = '%s' AND type = 'd';",vrpath,usrname);
    int qret = mysql_query(mysql,sql);
    if(qret != 0){
        fprintf(stderr,"%s:%s\n","mysql_query",mysql_error(mysql));
    }
    return 0;
}
